<?php
abstract class BaseControl extends Object
{
    protected $name;
    protected $underscoreName;
    protected $resourceId;
    protected $template;
    protected $templateFile;
    protected $data;
    protected $useTemplate = true;
    protected $config;
    protected $cssFile;
    protected $jsFile;
    protected $jsClass;
    protected $cssClass;

    public function BaseControl($name = null)
	{
        if (!$this->name) $this->name = $name ? $name : $this->GetClassName();
        $this->underscoreName = $this->GetUnderscoreName();
        $this->config = $this->GetConfig();

        if (is_null($this->templateFile))
            $this->templateFile = String::CropEnd('Control', $this->GetClassName()).'.html';
        $this->SetTemplate();

        $this->config->AddCss($this->cssFile);
        $this->config->AddSharedJs($this->jsFile);
	}

    public function GetConfig()
    {
        return BaseConfig::GetInstance();
    }

    protected function GetClassNameForTemplate()
    {
        return $this->GetClassName();
    }

    public function GetTemplatePath()
    {
        $fileName = FileHandler::GetNameFromClass($this->GetClassNameForTemplate());
        $path = FileHandler::GetUsingPath($fileName);
        $path = String::CropBegin($this->config->DIR_CONTROLS, $path);
        $path = String::CropEnd($fileName, $path);
        return $this->config->DIR_HTML_CONTROLS.$path;
    }

    public function GetElementPath()
    {
        return $this->GetTemplatePath().DS.$this->underscoreName;
    }

    public function Render()
    {
        if ($this->template)
        {
            $this->template->Replace('control_name', $this->name);
            $this->template->Replace('refresh_url', $this->GetRefreshUrl());
            return $this->template->Replace(AppConfig::GetInstance()->GetReplaceValues());
        }
    }

    protected function SetTemplate($filename = null)
    {
        if (!$this->useTemplate) return;

        if (is_null($filename))
            $filename = $this->templateFile;

        if (!String::Contains('.html', $filename))
            $filename .= '.html';
    	$this->template = new Template($filename, $this->GetTemplatePath());
    }

    public function Replace($key, $value = null)
    {
    	return $this->GetTemplate()->Replace($key, $value);
    }

	public function Repeat($zone, $data, $callback = null)
	{
		return $this->GetTemplate()->Repeat($zone, $data, $callback);
	}

    protected function RepeatTree($zone, $data, $child_key, $callback = null)
	{
		return $this->GetTemplate()->RepeatTree($zone, $data, $child_key, $callback);
	}

    protected function ReplaceTemplate($key, $template)
    {
		return $this->Replace($key, $template->Render());
    }

    protected function ReplaceElement($element_name, $path = null)
    {
		$temp = $this->GetElementTemplate($element_name, $path);
		return $this->ReplaceTemplate($element_name, $temp);
    }

    protected function GetElementTemplate($element_name, $path = null)
    {
    	if (is_null($path)) $path = $this->GetElementPath();
        $element_name = String::Pascalize($element_name);
		return new Template("$element_name.html", $path);
    }

    protected function GetUnderscoreName()
    {
		return String::CropEnd('_control', String::Underscore($this->GetClassName()));
    }

    protected function GetTemplate()
    {
        if (is_null($this->template))
            $this->SetTemplate();
        return $this->template;
    }

    protected function GetRefreshUrl()
    {
        return AppConfig::GetInstance()->URL.FS.RequestHandler::GetInstance()->url.'?__cr='.$this->GetClassName();
    }

    protected function ProcessRequest()
    {
        $action = RequestHandler::Get('action');
        $action = $action ? $action : 'Render';
        $reflect = new ReflectionMethod($this->GetClassName(), $action);
        $params = $reflect->getParameters();
        $args = array();
        foreach ($params as $param)
        {
            $args[] = RequestHandler::Get($param->name);
        }
        return $reflect->invokeArgs($this, $args);
    }

    public function GetResourceId()
    {
        return $this->resourceId;
    }

    public function FlashMessage()
    {
        $this->Replace('msgflash', MessageControl::Flash());
    }

    public function RenderStub()
    {
        $refresh_url = $this->GetRefreshUrl();
        $js = $this->GetJsScript();
        return "<div class='{$this->cssClass}' id='{$this->name}' url='$refresh_url'></div>$js";
    }

    protected function GetJsScript()
    {
        return "<script>new {$this->jsClass}('{$this->name}')</script>";
    }

    public function GetName()
    {
        return $this->name;
    }
}
?>
